package com.fz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fz.entity.Goods;
import com.fz.entity.OrderGoods;
import com.fz.entity.Orders;
import com.fz.entity.TUser;
import com.fz.mapper.OrdersMapper;
import com.fz.service.GoodsService;
import com.fz.service.OrderGoodsService;
import com.fz.service.OrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fz.service.TUserService;
import com.fz.util.FzUtil;
import com.fz.vo.GoodsVo;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.MathContext;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author fz
 * @since 2024-08-20
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {
    @Resource
    OrdersMapper ordersMapper;
    @Resource
    TUserService tUserService;
    @Resource
    PasswordEncoder passwordEncoder;
    @Resource
    GoodsService goodsService;
    @Resource
    OrderGoodsService orderGoodsService;

    public List<GoodsVo> getByOrderId(Long orderId) {
        List<GoodsVo> goodsVoList = ordersMapper.getByOrderId(orderId);
        for (GoodsVo goodsVo : goodsVoList) {
            if (null != goodsVo.getImgs()){
                goodsVo.setImagePathList(goodsVo.getImgs().split(";"));
            }
            if (null != goodsVo.getCount() && null != goodsVo.getPrice()) {
                Long count = Long.valueOf(goodsVo.getCount());
                BigDecimal decimalCount = BigDecimal.valueOf(count);
                BigDecimal totalAmount = goodsVo.getPrice().multiply(decimalCount);
                goodsVo.setTotalAmount(totalAmount);
            }
        }
        return goodsVoList;
    }

    public void setGoodsList(Page<Orders> ordersPage) {
        List<Orders> ordersList = ordersPage.getRecords();
        for (Orders orders : ordersList) {
            List<GoodsVo> goodsVoList = getByOrderId(orders.getId());
            orders.setGoodsList(goodsVoList);
        }
        ordersPage.setRecords(ordersList);
    }


    @Override
    public Page<Orders> getList(Long userId, Integer pageNo, Integer pageSize) {
        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("create_time");
        Page<Orders> ordersPage;
        if(userId == -1) {
            ordersPage = this.page(new Page<>(pageNo, pageSize), wrapper);
            setGoodsList(ordersPage);
        }else {
            wrapper.eq("user_id", userId);
            ordersPage = this.page(new Page<>(pageNo, pageSize), wrapper);
            setGoodsList(ordersPage);

        }
        return ordersPage;
    }

    @Override
    public Page<Orders> searchByOrderId(Long userId, Integer pageNo, Integer pageSize, String searchVal) {
        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
        wrapper.like("order_id", searchVal);
        if(userId!=-1){
            wrapper.eq("user_id", userId);
        }
        Page<Orders> ordersPage = this.page(new Page<>(pageNo, pageSize),wrapper);
        setGoodsList(ordersPage);
        return ordersPage;
    }

    @Override
    public Page<Orders> getByOrderStatus(Long userId, String status, Integer pageNo, Integer pageSize) {
        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("create_time");
        if(userId!=-1){
            wrapper.eq("user_id", userId);
        }
        wrapper.eq("order_status",status);
        Page<Orders> ordersPage = this.page(new Page<>(pageNo,pageSize),wrapper);
        setGoodsList(ordersPage);
        return ordersPage;
    }

    @Override
    public Page<Orders> getByTimeRange(Long userId, String maxTime, String minTime, Integer pageNo, Integer pageSize) {
        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
        LocalDateTime min = null;
        LocalDateTime max = null;
        if(!maxTime.isEmpty() && !minTime.isEmpty()) {
            min = LocalDateTime.parse(minTime);
            max = LocalDateTime.parse(maxTime);
            System.out.println(min);
            System.out.println(max);
            wrapper.between("create_time", minTime, maxTime);
        }
        if(userId!=-1){
            wrapper.eq("user_id", userId);
        }
        Page<Orders> ordersPage = this.page(new Page<>(pageNo, pageSize),wrapper);
        setGoodsList((ordersPage));
        return ordersPage;
    }

    @Override
    @Transactional
    public Long createOrder(Long userId, BigDecimal totalAmount, Long[] goodsIds, Integer[] counts, Long storeId) {
        boolean flag = true;
        String orderCode = FzUtil.randomOrderCode("OR");
        Orders orders = new Orders(
                orderCode,
                userId,
                totalAmount,
                "余额支付",
                "自提",
                "未付款",
                LocalDateTime.now());
        if (!this.save(orders)) {
            throw new RuntimeException("系统异常");
        }

        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", orderCode);
        Orders one = this.getOne(wrapper);
        for (int i = 0; i < goodsIds.length; i++) {
            System.out.println(i);
            if(!orderGoodsService.save(new OrderGoods(one.getId(), goodsIds[i], storeId, counts[i]))) {
                throw new RuntimeException("系统异常");
            }
        }
        return one.getId();
    }

    @Override
    public Orders getById(Long id) {
        Orders orders = super.getById(id);
        orders.setGoodsList(getByOrderId(orders.getId()));
        return orders;
    }

    @Override
    public Boolean payTheOrder(String password, Long orderId, Long userId) {
        Orders orderInfo = getById(orderId);
        TUser user = tUserService.getById(userId);
        // 密码正确
        if(passwordEncoder.matches(password, user.getPassword())) {
            // 扣钱
            MathContext mathContext = MathContext.DECIMAL32;
            BigDecimal result = user.getAccount().subtract(orderInfo.getTotalAmount(), mathContext);
//            System.out.println("用户余额"+user.getAccount());
//            System.out.println("结果"+result);
            user.setAccount(result);
            tUserService.updateById(user);
            // 订单状态更新
            orderInfo.setOrderStatus("已付款");
            orderInfo.setUpdateTime(LocalDateTime.now());
            this.updateById(orderInfo);
            // 商品相关修改
            List<GoodsVo> goodsList = orderInfo.getGoodsList();
            for (GoodsVo goodsVo : goodsList) {
                Goods goods = goodsService.getById(goodsVo.getId());
                goods.setSales(goods.getSales() + goodsVo.getCount());
                goods.setStore(goods.getStore() - goodsVo.getCount());
                goodsService.updateById(goods);
            }
        } else {
            return false;
        }
        return true;
    }

    @Override
    @Transactional
    public Boolean batchShipOrders(Long[] ids, String orderStatus) {
        for (Long id : ids) {
            if (!this.updateById(new Orders(id,orderStatus))){
                throw new RuntimeException("发货失败");
            }
        }
        return true;
    }


}
